package com.authine.cloudpivot.ext.service.invoice;

import com.alibaba.cola.dto.SingleResponse;
import com.authine.cloudpivot.ext.Enum.InvoiceStatus;
import com.authine.cloudpivot.ext.applicationservice.InvoiceRecordService;
import com.authine.cloudpivot.ext.dto.base.Ids;
import com.authine.cloudpivot.ext.dto.base.PageList;
import com.authine.cloudpivot.ext.dto.form.InvoiceApplyForm;
import com.authine.cloudpivot.ext.dto.form.InvoiceApplyUpdateForm;
import com.authine.cloudpivot.ext.dto.model.invoice.*;
import com.authine.cloudpivot.ext.dto.model.settle.Settle;
import com.authine.cloudpivot.ext.dto.model.trade.Trade;
import com.authine.cloudpivot.ext.dto.query.IdType;
import com.authine.cloudpivot.ext.dto.query.InvoiceQuery;
import com.authine.cloudpivot.ext.service.InvoiceVoucherService;
import com.authine.cloudpivot.ext.service.bill.BillService;
import com.authine.cloudpivot.ext.service.bill.impl.BillServiceImpl;
import com.authine.cloudpivot.ext.service.goldentax.GoldenTaxService;
import com.authine.cloudpivot.ext.service.goldentax.impl.GoldenTaxServiceImpl;
import com.authine.cloudpivot.ext.service.invoice.impl.InvoiceDetailBillServiceImpl;
import com.authine.cloudpivot.ext.service.invoice.impl.InvoiceDetailServiceImpl;
import com.authine.cloudpivot.ext.service.organiztion.OrganizationService;
import com.authine.cloudpivot.ext.service.settle.SettleService;
import com.authine.cloudpivot.ext.service.settle.impl.SettleServiceImpl;
import com.authine.cloudpivot.ext.service.trade.TradeService;
import com.authine.cloudpivot.ext.service.trade.impl.TradeServiceImpl;
import com.authine.cloudpivot.ext.service.voucher.KingDeeFinanceService;
import com.authine.cloudpivot.ext.service.voucher.impl.KingDeeFinanceServiceImpl;
import com.authine.cloudpivot.ext.utils.BigDecimalUtils;
import com.authine.cloudpivot.ext.utils.RecordingVoucherPmUtil;
import com.authine.mvp.app.launcher.domain.utills.ApplicationContextUtils;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.lang.NonNull;

import java.math.BigDecimal;
import java.util.Collection;
import java.util.List;
import java.util.function.BiFunction;

public interface InvoiceApplyService {
    BiFunction<ApplyInvoiceDetailDto, BigDecimal, BigDecimal> applyInvoiceDetailAmountFun = (invoiceDetail, cumulative) -> BigDecimalUtils.add(invoiceDetail.getAmount(), cumulative);
    BiFunction<ApplyInvoiceDetailDto, BigDecimal, BigDecimal> applyInvoiceDetailTotalFun = (invoiceDetail, cumulative) -> BigDecimalUtils.add(invoiceDetail.getTotal(), cumulative);

    InvoiceRecordService invoiceRecordService = new InvoiceRecordService();
    GoldenTaxService goldenTaxService = new GoldenTaxServiceImpl();
    TradeService tradeService = new TradeServiceImpl();
    BillService billService = new BillServiceImpl();
    InvoiceDetailBillService invoiceDetailBillService = new InvoiceDetailBillServiceImpl();
    InvoiceDetailService invoiceDetailService = new InvoiceDetailServiceImpl();
    SettleService settleService = new SettleServiceImpl();
    NamedParameterJdbcTemplate jdbcTemplate =  ApplicationContextUtils.getBean(NamedParameterJdbcTemplate.class);

    InvoiceVoucherService invoiceVoucherService = new InvoiceVoucherService();
    RecordingVoucherPmUtil recordingVoucherPmUtil = new RecordingVoucherPmUtil();
    KingDeeFinanceService kingDeeFinanceService = new KingDeeFinanceServiceImpl();

    String BalanceMessages = "补差金额大于1.0";
    /**
     * 最大申请开票未税金额
     */
    BigDecimal MAX_INVOICE = new BigDecimal(100000.00);
    /**
     * 南阳固买增值税专用发票最大申请开票未税金额，一般服务费发票都是增值税专用发票
     */
    BigDecimal NANYANG_VAT_SPECIAL_MAX_INVOICE = new BigDecimal(10000.00);

    InvoiceApply loadById(String id);

    List<InvoiceApply> loadListByIds(List<String> ids);

    List<ApplyInvoiceDetailDto> viewCanInvoice(IdType idType);

    /**
     * 创建货物发票申请单
     * @param invoiceApplyFormList
     * @return 发票申请单IDS
     */
    List<String> createProductInvoice(List<InvoiceApplyForm> invoiceApplyFormList);

    /**
     * 创建服务费发票申请单
     * @param invoiceApplyFormList
     * @return 服务费发票申请单ID
     */
    List<String> createServiceInvoice(List<InvoiceApplyForm> invoiceApplyFormList);

    /**
     * 提交发票申请单(NEW和Returned状态的发票单)
     * @param invoiceIds 发票申请单
     */
    void submit(List<String> invoiceIds);

    /**
     * 确认开票操作
     * @param makeInvoice
     * @return
     */
    InvoiceApply confirmInvoice(MakeInvoice makeInvoice);

    /**
     * 确认收票操作
     * @param confirmInvoice
     */
    void receiveInvoice(ConfirmInvoice confirmInvoice);

    /**
     * 撤销开票
     * @param invoiceIds
     */
    void invoiceRollback(List<String> invoiceIds);

    /**
     * 发票红冲(服务费、货物发票)
     * @param offsetInvoice
     */
    void offsetInvoice(OffsetInvoice offsetInvoice);

    /**
     * 执行回写发票可核销金额和已核销金额
     * 调用点：
     * 1、发票红冲
     * 2、平台采购付款管理-平台付款申请单-关闭结算
     * 3、删除结算单及明细
     * 4、创建采购结算单
     * 5、提交采购结算单
     * 6、结算单核销
     *
     * @param invoiceApplyIds  参与回写发票单Id列表
     */
    void writeBackInvoiceWriteOffAmountByInvoiceApply(List<String> invoiceApplyIds);

    /**
     * 根据条件关闭申请单
     * @param invoiceIds 要关闭的申请单ID
     * @param status 符合关闭条件的状态
     */
    List<String> close(List<String> invoiceIds, List<InvoiceStatus> status);

    /**
     * 回写发票申请单对应交易记录的发票号码
     * @param invoiceIds 发票申请单ID
     */
    void writeBackTradeInvoiceNumber(Collection<String> invoiceIds);

    /**
     * 修改开票信息
     */
    void updateInvoice(InvoiceApplyUpdateForm invoiceDto);

    /**
     * 货物发票单红冲.
     *
     * @param offsetInvoice 红冲参数
     * @param invoice       源蓝票单
     * @return 保存成功的红字发票单
     */
    InvoiceApply goodsOffset(@NonNull OffsetInvoice offsetInvoice, @NonNull InvoiceApply invoice);

    /**
     * 查询发票申请单
     * @param query
     * @return
     */
    PageList<InvoiceApply> page(InvoiceQuery query);

    /**
     * 发票创建前的统一验证 （销售和采购发票）
     * @param invoiceApplyForm 开票信息
     */
    void verifyCreate(InvoiceApplyForm invoiceApplyForm);

    SingleResponse approveInvoice(InvoiceApprove invoiceApprove);


}
